package com.molichuxing.gateway.api.aspect;

import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.molichuxing.gateway.api.config.OptionalLogConfig;
import com.molichuxing.gateway.bff.permission.entity.request.OperationLogCreateVo;
import com.molichuxing.gateway.bff.permission.services.OperationLogBffService;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.gateway.utils.entity.DealerEntity;
import com.molichuxing.gateway.utils.entity.UserEntity;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

@Aspect
@Order(10)
public class LogAopActionAspect {

    private final static Logger logger = LoggerFactory.getLogger(LogAopActionAspect.class);

    /**
     * 注入service,用来将日志信息保存在数据库
     */
    @Resource
    private OperationLogBffService operationLogBffService;

    @Resource
    private TokenUtil tokenUtil;

    /**
     * 配置接入点，即为所要记录的action操作目录
     */
    @Pointcut("execution(* com.molichuxing.gateway.api.services..*.*(..))")
    private void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object doBefore(ProceedingJoinPoint pjp) throws Throwable {
        //日志实体对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        // 拦截的实体类，就是当前正在执行的controller
        Object target = pjp.getTarget();
        // 拦截的方法名称。当前正在执行的方法
        String methodName = pjp.getSignature().getName();
        // 拦截的放参数类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Class[] parameterTypes = msig.getMethod().getParameterTypes();
        Object object = null;
        // 获得被拦截的方法
        Method method = null;
        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            e1.printStackTrace();
        } catch (SecurityException e1) {
            e1.printStackTrace();
        }
        if (null != method) {
            // 获取方法（此为自定义注解）
            OptionalLogConfig op = method.getAnnotation(OptionalLogConfig .class);
            if(null != op) {
                try{
                    DealerEntity dealerEntity = RequestAttrUtil.getCurrentDealer();
                    OperationLogCreateVo operationLog = new OperationLogCreateVo();
                    operationLog.setDealerId(dealerEntity.getId());
                    operationLog.setAction(request.getRequestURI());
                    operationLog.setContent(op.methods());
                    UserEntity user = tokenUtil.getUser(request.getHeader("token"));
                    operationLog.setAccountId(user.getAccountId());
                    operationLog.setAccountName(user.getRealName());
                    operationLog.setGroupId(user.getGroupId());
                    operationLog.setGroupName(user.getGroupName());
                    operationLogBffService.createOperationLog(operationLog);
                }catch(Exception ex) {
                    logger.error("插入操作日志失败");
                }
            }
        }
        return pjp.proceed();
    }
}
